#include <func.h>
#include "UserInfo.h"
#include "Command.h"
#include "Request.h"
#include "Response.h"
#include "Crypto.h"

int do_login(int connfd, UserInfo* info)
{
}

int do_register(int connfd)
{
    for (;;) {
        char username[26] = "";
        char passwd[26] = "";
        char confirm[26] = "";

        printf("用户名: ");
        scanf("%s", username);

        // 禁用回显
        struct termios old_termios;
        disable_echo(STDIN_FILENO, &old_termios);

        printf("密码: ");
        scanf("%s", passwd);
        printf("\n");
        printf("确认密码: ");
        scanf("%s", confirm);
        printf("\n");

        // 恢复回显
        restore_echo(STDIN_FILENO, &old_termios);

        if (strcmp(passwd, confirm) != 0) {
            printf("密码不一致, 请重新输入!\n");
            continue;
        }
        // 1. 密码一致, 构建 Request
        Request req;
        bzero(&req, sizeof(req));
        req.type = REQ_REGISTER;
        // 用户名 密码
        sprintf(req.value, "%s %s", username, passwd);
        printf("DEBUG: %s\n", req.value);

        // 设置 req.length
        req.length = strlen(req.value);

        // 2. 发送 Request 
        int length = 2 * sizeof(int) + req.length; 
        send(connfd, &length, sizeof(int), MSG_WAITALL);
        send(connfd, &req, length, MSG_WAITALL);

        // 3. 接收 Response
        Response resp;
        bzero(&resp, sizeof(resp));
        recv(connfd, &length, sizeof(int), MSG_WAITALL);
        recv(connfd, &resp, length, MSG_WAITALL);

        switch (resp.status) {
        case RESP_OK:
            printf("恭喜您，注册成功!\n");
            return 0;   // 注册成功
        case RESP_EXIST:
            printf("用户名已存在!\n");
            continue;
        // other cases...
        }
    }
    return -1;  // 注册失败
}

void login_or_register(int connfd, UserInfo* info)
{
    printf("请选择 (L)登录, (R)注册, (E)退出: ");
    fflush(stdout);

    char c;
    scanf(" %c", &c);
    while (getchar() != '\n')   // 跳过这一行剩余的字符
        ;
    
    switch(c) {
    case 'L': case 'l':
        do_login(connfd, info);
        break;
    case 'R': case 'r':
        do_register(connfd);
        break;
    case 'E': case 'e':
        exit(0);
        break;
    default:
        printf("输入有误，请重新输入\n");
        break;
    }
}

void upload_file(int connfd, const char* file)
{
    Request req;
    req.type = REQ_UPLOAD_FILE;
    // 文件大小, sha256sum, 服务器端存储的绝对路径 
    int fd = open(file, O_RDONLY);
    struct stat fstatus;
    fstat(fd, &fstatus);
    long fsize = fstatus.st_size;

    char cmd[1024];
    sprintf(cmd, "sha256sum %s", file);
    FILE* pipe = popen(cmd, "r");

    char sha256sum[65] = {'\0'};
    fread(sha256sum, 1, 64, pipe);

    // 服务器端存储的路径：/username/用户的当前工作目录/filename
    char server_path[1024] = "/peanut/dir/a.txt";
    sprintf(req.value, "%ld %s %s", fsize, sha256sum, server_path);

    req.length = strlen(req.value);

    int length = 2 * sizeof(int) + req.length;
    send(connfd, &length, sizeof(int), MSG_WAITALL);
    send(connfd, &req, length, MSG_WAITALL);

    Response resp;
    recv(connfd, &length, sizeof(int), MSG_WAITALL);
    recv(connfd, &resp, length, MSG_WAITALL);

    switch (resp.status) {
    case RESP_EXIST:
        close(fd);
        break;
    case RESP_NOEXIST:
        // 发送文件内容
        char buf[4096];
        int n;
        while ((n = read(fd, buf, 4096)) > 0) {
            send(connfd, buf, n, MSG_WAITALL);
        }
        close(fd);
        break;
    }
}
